/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.ucue.ptc.gco.ngc;

import edu.ucue.ptc.gco.dao.DetallePedidoDAOLocal;
import edu.ucue.ptc.gco.dao.LoteDAOLocal;
import edu.ucue.ptc.gco.dao.PedidoDAOLocal;
import edu.ucue.ptc.gco.mdl.Cliente;
import edu.ucue.ptc.gco.mdl.DetallePedido;
import edu.ucue.ptc.gco.mdl.Lote;
import edu.ucue.ptc.gco.mdl.Pedido;
import edu.ucue.ptc.gco.mdl.Producto;
import edu.ucue.ptc.gco.util.AtributoInvalidoException;
import edu.ucue.ptc.gco.util.InsuficienteStockException;
import edu.ucue.ptc.gco.util.PedidoException;
import edu.ucue.ptc.gco.util.ValidarAtributoUtil;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.inject.Named;

/**
 *
 * @author wilo
 */
@Stateless
@Named(value = "pedidoManager")
public class PedidoManager implements PedidoManagerLocal {

    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")
    @Inject
    private PedidoDAOLocal pedidoDAOLocal;
    @Inject
    private DetallePedidoDAOLocal detalleDAOLocal;
    @Inject
    private LoteDAOLocal loteDAO;
    @Inject
    private ProductoManagerLocal ejbProducto;
    @EJB
    private ClienteManagerLocal ejbCliente;
    @EJB
    private DireccionManagerLocal ejbDireccion;
    @Inject
    private UsuarioManagerLocal usuarioManager;

    @Override
    public void crear(Pedido pedido, String usuario, String password) throws AtributoInvalidoException, InsuficienteStockException, Exception, PedidoException {

        usuarioManager.existeUsuario(usuario, password);
        try {

            ValidarAtributoUtil.validarObjetoNulo("CLIENTE", pedido.getCliente());

            //Vaida que la fecha de entrega sea mayor q la fecha de Ingreso
            ValidarAtributoUtil.validarFecha("FECHA", pedido.getFechaIngreso(), pedido.getFechaEntrega());

            //validamos la direccion del cliente
            ValidarAtributoUtil.validarObjetoNulo("DIRECCION", pedido.getDireccion());
            //Cliente cliente = ejbCliente.buscarPorId(pedido.getCliente().getIdPersona());
            /*
             boolean direccion=false;
             for(int i=0; i<cliente.getDireccion().size(); i++)
             {
             if(ejbDireccion.obtenerPorId(pedido.getDireccion().getIdDireccion()+"")==cliente.getDireccion().get(i))
             direccion=true;
             }
             if (direccion==false)
             throw new PedidoException("Dirección ingresada no corresponde al cliente "+cliente.getApellidos()+" "+cliente.getNombres()+"");
             */
            //Validamos el Stock de cada producto en un DetallePedido
            for (int i = 0; i < pedido.getDetalle().size(); i++) {
                ValidarAtributoUtil.validarDoubleCero("CANTIDAD", pedido.getDetalle().get(i).getCantidad());

                Producto p = ejbProducto.obtenerPorId(pedido.getDetalle().get(i).getProducto().getIdProducto(), usuario, password);
                Long obtenerTotalStock = ejbProducto.obtenerTotalStock(p.getIdProducto(), usuario, password);

                if (pedido.getDetalle().get(i).getCantidad() > obtenerTotalStock) {
                    throw new InsuficienteStockException("No hay la cantidad suficiente (" + obtenerTotalStock + ") del producto con id " + p.getIdProducto() + "");
                }
                //else
                //detalleDAOLocal.crear(pedido.getDetalle().get(i));
            }

            //Calculamos costos de pedido
            pedido = calcularCosto(pedido, usuario, password);

            for (DetallePedido det : pedido.getDetalle()) {
                det.setPedido(pedido);
                ejbProducto.disminuirStock(det.getProducto().getIdProducto(), det.getCantidad(), usuario, password);
                //detalleDAOLocal.crear(det);
            }
            pedidoDAOLocal.crear(pedido);

        } catch (Exception ex) {
            if (ex instanceof AtributoInvalidoException) {
                throw (AtributoInvalidoException) ex;
            } else if (ex instanceof InsuficienteStockException) {
                throw (InsuficienteStockException) ex;
            } else if (ex instanceof PedidoException) {
                throw (PedidoException) ex;
            } else {
                ex.printStackTrace();
                throw new Exception("Error desconocido: " + ex.getLocalizedMessage() + " - " + ex.getCause());
            }
        }
    }
    @Override
    public void crear2(Pedido pedido, String usuario, String password) throws AtributoInvalidoException, InsuficienteStockException, Exception, PedidoException {

        usuarioManager.existeUsuario(usuario, password);
        try {

            ValidarAtributoUtil.validarObjetoNulo("CLIENTE", pedido.getCliente());
            //Vaida que la fecha de entrega sea mayor q la fecha de Ingreso
            ValidarAtributoUtil.validarFecha("FECHA", pedido.getFechaIngreso(), pedido.getFechaEntrega());
            //validamos la direccion del cliente
            ValidarAtributoUtil.validarObjetoNulo("DIRECCION", pedido.getDireccion());
            for (int i = 0; i < pedido.getDetalle().size(); i++) {
                if(pedido.getDetalle().get(i).getProducto().equals(null)!=true)
                    ValidarAtributoUtil.validarDoubleCero("CANTIDAD", pedido.getDetalle().get(i).getCantidad());
                    Producto p = ejbProducto.obtenerPorId(pedido.getDetalle().get(i).getProducto().getIdProducto(), usuario, password);
                    Long obtenerTotalStock = ejbProducto.obtenerTotalStock(p.getIdProducto(), usuario, password);

                    if (pedido.getDetalle().get(i).getCantidad() > obtenerTotalStock) {
                        throw new InsuficienteStockException("No hay la cantidad suficiente (" + obtenerTotalStock + ") del producto con id " + p.getIdProducto() + "");
                    }
            }
            //Calculamos costos de pedido
            pedido = calcularCosto2(pedido, usuario, password);
            for (DetallePedido det : pedido.getDetalle()) {
                det.setPedido(pedido);
                ejbProducto.disminuirStock2(det.getProducto().getIdProducto(), det.getCantidad(), det.getLote().getIdLote(),usuario, password);
                //detalleDAOLocal.crear(det);
            }
            pedidoDAOLocal.crear(pedido);
            
            
        } catch (Exception ex) {
            if (ex instanceof AtributoInvalidoException) {
                throw (AtributoInvalidoException) ex;
            } else if (ex instanceof InsuficienteStockException) {
                throw (InsuficienteStockException) ex;
            } else if (ex instanceof PedidoException) {
                throw (PedidoException) ex;
            } else {
                ex.printStackTrace();
                throw new Exception("Error desconocido: " + ex.getLocalizedMessage() + " - " + ex.getCause());
            }
        }
    }

    @Override
    public void actualizar(Pedido pedido, String usuario, String password) throws PedidoException, Exception {
        usuarioManager.existeUsuario(usuario, password);

        try {
            Pedido obtenerId = obtenerPorId(pedido.getIdPedido(), usuario, password);
            if (obtenerId == null) {
                throw new PedidoException("Objeto Pedido nulo");
            } else {
                pedidoDAOLocal.actualizar(pedido);
            }
        } catch (PedidoException ex) {
            if (ex instanceof PedidoException) {
                throw (PedidoException) ex;
            } else {
                ex.printStackTrace();
                throw new Exception("Error desconocido: " + ex.getLocalizedMessage() + " - " + ex.getCause());
            }
        }
    }

    @Override
    public void eliminar(Pedido pedido, String usuario, String password) throws PedidoException, Exception {
        usuarioManager.existeUsuario(usuario, password);

        try {
            Pedido obtenerId = obtenerPorId(pedido.getIdPedido(), usuario, password);
            if (obtenerId == null) {
                throw new PedidoException("Objeto Pedido nulo");
            } else {
                pedidoDAOLocal.eliminar(pedido);
            }
        } catch (PedidoException ex) {
            if (ex instanceof PedidoException) {
                throw (PedidoException) ex;
            } else {
                ex.printStackTrace();
                throw new Exception("Error desconocido: " + ex.getLocalizedMessage() + " - " + ex.getCause());
            }
        }

    }

    @Override
    public List<Pedido> listarTodos(String usuario, String password) throws PedidoException, Exception {
        usuarioManager.existeUsuario(usuario, password);

        return pedidoDAOLocal.listarTodos();
    }

    @Override
    public Pedido obtenerPorId(int idPedido, String usuario, String password) throws PedidoException, Exception {
        usuarioManager.existeUsuario(usuario, password);

        return pedidoDAOLocal.obtenerPorId(idPedido);
    }

    public Pedido calcularCosto(Pedido pedido, String usuario, String password) throws Exception, AtributoInvalidoException {

        double iva = 0, aux = 0, subtotal = 0;
        List<DetallePedido> detallePedido = pedido.getDetalle();

        for (int i = 0; i < detallePedido.size(); i++) {
            ValidarAtributoUtil.validarDoubleCero("CANTIDAD", pedido.getDetalle().get(i).getCantidad());

            Producto p = ejbProducto.obtenerPorId(detallePedido.get(i).getProducto().getIdProducto(), usuario, password);
            List<Lote> lotes = detallePedido.get(i).getProducto().getLotes();
            aux = (detallePedido.get(i).getCantidad() * loteDAO.obtenerPorId(lotes.get(0).getIdLote()).getCostoVenta());

            if (detallePedido.get(i).getIva() == true) {
                detallePedido.get(i).setTotal(aux + (aux * 0.12));
                iva = iva + (aux * 0.12);
            } else {
                detallePedido.get(i).setTotal(aux);
            }

            subtotal = subtotal + aux;
        }
        pedido.setIva(iva);
        pedido.setSubtotal(subtotal);
        pedido.setTotal(subtotal + iva);
        return pedido;
    }
    
    public Pedido calcularCosto2(Pedido pedido, String usuario, String password) throws Exception, AtributoInvalidoException {

        double iva = 0, aux = 0, subtotal = 0;
        List<DetallePedido> detallePedido = pedido.getDetalle();

        for (int i = 0; i < detallePedido.size(); i++) {
            ValidarAtributoUtil.validarDoubleCero("CANTIDAD", pedido.getDetalle().get(i).getCantidad());

            Producto p = ejbProducto.obtenerPorId(detallePedido.get(i).getProducto().getIdProducto(), usuario, password);
            Lote lote = detallePedido.get(i).getLote();
            aux = (detallePedido.get(i).getCantidad() * loteDAO.obtenerPorId(lote.getIdLote()).getCostoVenta());

            if (detallePedido.get(i).getIva() == true) {
                detallePedido.get(i).setTotal(aux + (aux * 0.12));
                iva = iva + (aux * 0.12);
            } else {
                detallePedido.get(i).setTotal(aux);
            }

            subtotal = subtotal + aux;
        }
        pedido.setIva(iva);
        pedido.setSubtotal(subtotal);
        pedido.setTotal(subtotal + iva);
        return pedido;
    }
}
